<template>
    <div>
        <div id="container"></div>
        <div class="input-card" style="width: 120px">
            <button class="btn" @click="loadData()" >加载数据</button>
            <button class="btn" @click="createPolygon()" style="margin-bottom: 5px">新建</button>
            <button class="btn" @click="startPolygonEdit()" style="margin-bottom: 5px">开始编辑</button> 
            <button class="btn" @click="stopPolygonEdit()">结束编辑</button> 
            <button class="btn" @click="clearAll()">清空</button>
            <button class="btn" @click="printPolygon()">打印</button> 
            <button class="btn" @click="saveRegionData()">保存</button>
        </div>
        <el-dialog title="区域设置" :visible.sync="editorDialogVisible">
            <el-form :model="form">
                <el-form-item label="区域编码" :label-width="formLabelWidth">
                    <el-input v-model="form.code" autocomplete="off"></el-input>
                </el-form-item>
                <el-form-item label="区域名称" :label-width="formLabelWidth">
                    <el-input v-model="form.name" autocomplete = "off"></el-input>
                </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="editorDialogVisible = false">取 消</el-button>
                <el-button type="primary" @click="savePolygonData()">确 定</el-button>
            </div>
        </el-dialog>
    </div>
</template>

<script>
import AMapLoader from '@amap/amap-jsapi-loader';
import { listRegionshape, getRegionshape, delRegionshape, addRegionshape, updateRegionshape, exportRegionshape } from "@/api/grid/regionshape";

let mapdemo = {
    name: "mapdemo",
    data(){
        return {
            map:null,
            polygonEditor: null,
            polygons: [],
            editorDialogVisible: false,
            form: {
                code: "",
                name: "",
                polygon: null
            },
            formLabelWidth: '120px',
            polyContextMenu: null,
            selectedPolygon: null,
            holeEdit: false,
            activePolygons: new Map() ,
            regiondatas:[],
            wkt:{
                polygon: "POLYGON",
                multipolygon: "MULTIPOLYGON",
                point:"POINT"
            }
        }
    },
    methods:{
        wkt2PolygonPath(wkt){
            let res = []
            if(wkt.startsWith(this.wkt.polygon)){
                wkt = wkt.substring(this.wkt.polygon.length+1,wkt.length-1)
                let paths = wkt.split('),(')
                for(let j = 0;j<paths.length;j++){
                    let temp = []
                    let path = paths[j]
                    let lnglats = path.replace(/\(/g , '').replace(/\)/g,'').split(',')
                    for(let i = 0;i<lnglats.length;i++){
                        const lnglat = lnglats[i].trim().split(' ')
                        
                        temp.push([parseFloat(lnglat[0].trim()),parseFloat(lnglat[1].trim())])
                    }
                    res.push(temp)
                }
                return res;
            }else if(wkt.startsWith(this.wkt.multipolygon)){
                wkt = wkt.substring(this.wkt.multipolygon.length+1,wkt.length-1)
                let polygons = wkt.split(')),((')
                
                for(let k = 0;k<polygons.length;k++){
                    let polygonTmp = []
                    let paths = polygons[k].split('),(')
                    for(let j = 0;j<paths.length;j++){
                        let temp = []
                        let path = paths[j]
                        let lnglats = path.replace(/\(/g , '').replace(/\)/g,'').split(',')
                        for(let i = 0;i<lnglats.length;i++){
                            const lnglat = lnglats[i].trim().split(' ')
                            
                            temp.push([parseFloat(lnglat[0].trim()),parseFloat(lnglat[1].trim())])
                        }
                        polygonTmp.push(temp)
                    }
                    res.push(polygonTmp)
                }
                return res;
            }else if(wkt.startsWith(this.wkt.point)){
                wkt = wkt.substring(this.wkt.point.length+1,wkt.length-1)
                let lnglats = wkt.replace(/\(/g , '').replace(/\)/g,'').split(' ')
                return [parseFloat(lnglats[0].trim()),parseFloat(lnglats[1].trim())]
            }
        },
        loadData(){
            let queryParams = {
                pageNum: 1,
                pageSize: 1000,
                code: null,
                name: null,
            }
            listRegionshape(queryParams)
                .then(res=>{
                    this.clearAll()
                    let regionshapeList = res.rows;
                    regionshapeList.forEach((regionshape)=>{
                        const path = this.wkt2PolygonPath(regionshape.polygon)
                        console.log(JSON.stringify(path))
                        if(regionshape.polygon.startsWith(this.wkt.multipolygon)){
                            for(let i =0 ;i<path.length;i++){
                                let polygon = new AMap.Polygon({
                                    path: path[i],
                                    fillColor: '#ccebc5',
                                    strokeOpacity: 1,
                                    fillOpacity: 0.5,
                                    strokeColor: '#2b8cbe',
                                    strokeWeight: 1,
                                    strokeStyle: 'dashed',
                                    strokeDasharray: [5, 5],
                                })
                                polygon.setExtData(Object.assign({},regionshape))
                                polygon.getExtData().hasHole = true
                                this.addText(polygon)
                                this.addPolygonEvent(polygon)
                                this.map.add(polygon)
                                this.map.setFitView(polygon)
                            }
                        }else{
                            let polygon = new AMap.Polygon({
                                path: path,
                                fillColor: '#ccebc5',
                                strokeOpacity: 1,
                                fillOpacity: 0.5,
                                strokeColor: '#2b8cbe',
                                strokeWeight: 1,
                                strokeStyle: 'dashed',
                                strokeDasharray: [5, 5],
                            })
                            polygon.setExtData(regionshape)
                            polygon.getExtData().hasHole = true
                            this.addText(polygon)
                            this.addPolygonEvent(polygon)
                            this.map.add(polygon)
                        }
                        
                    });
                })
        },
        saveRegionData(){
            this.printPolygon()
            this.regiondatas.forEach(regiondata=>{
                if(regiondata.id == null){
                    addRegionshape(regiondata)
                    .then(res=>{
                        this.msgSuccess("新增成功");
                    })
                }else{
                    updateRegionshape(regiondata)
                    .then(res=>{
                        this.msgSuccess("更新成功");
                    })
                }
            })
        },
        parseAPolygon(path){
            //path一定是一个普通多边形
            let res ;
            for (var i = 0; i < path.length; i++) {
                if(i == 0){
                    res = "(" + path[i].lng + " " + path[i].lat;
                }else{
                    res += ", " + path[i].lng + " " + path[i].lat + "";
                }
            }
            res += ")";
            return res;
        },
        polygonToWKT(polygons) {
            let wkt ="";
            if(polygons.length == 1){
                wkt = "POLYGON"                
            }else{
                wkt = "MULTIPOLYGON"
            }
            let allAolygonRes =[]
            for(let i = 0 ;i <polygons.length;i++){
                let polygon = polygons[i]
                let rings = polygon.getPath();
                
                let polygonRes;
                if(rings[0].className == "AMap.LngLat"){
                    //普通的一个多边形
                    polygonRes = this.parseAPolygon(rings)
                }else{
                    //带孔多边形
                    for (var j = 0 ;j < rings.length; j++){
                        if(j==0){
                            polygonRes = this.parseAPolygon(rings[j])
                        }else{
                            polygonRes += ","+this.parseAPolygon(rings[j])
                        }
                    }
                }
                allAolygonRes.push(`(${polygonRes})`)
            }
            wkt = wkt+"("+allAolygonRes.join(",")+")"
            return wkt;
        },
        demo(){
            var polygon1 = new AMap.Polygon({
                path: [[[120.34620399999999,36.076808],[120.348607, 36.069732],[120.36834800000001, 36.085132],[120.34955099999999, 36.094218],[120.34603199999998, 36.08783699999998]],[[120.35126800000002, 36.08506299999999],[120.35118199999998, 36.079930000000004],[120.358048, 36.08131700000003],[120.35830600000001, 36.08582599999997]],[[120.34990208129841,36.089876378318934],[120.3494068249265,36.08680801346702],[120.35601024321888,36.08689695326417],[120.35562504381849, 36.08983191011846],[120.34990208129841, 36.089876378318934]]],
                fillColor: '#00FF00',
                strokeColor: '#FF0000'
            });
            this.addPolygonEvent(polygon1)
            this.map.add(polygon1)
            this.map.setFitView(polygon1)
        },
        addPolygon(path){
            var polygon = new AMap.Polygon({
                path: path,
                fillColor: '#00FF00',
                strokeColor: '#FF0000'
            });
            this.addPolygonEvent(polygon)
            this.map.add(polygon)
        },
        addPolygonEvent(polygon){
            polygon.on('dblclick',(event)=>{
                
                this.polygonEditor.close()
                this.selectedPolygon = polygon
                this.form.id = polygon.getExtData().id
                this.form.name = polygon.getExtData().name;
                this.form.code = polygon.getExtData().code;
                this.form.polygon = polygon;
                //右键菜单
                this.polyContextMenu.open(this.map, event.lnglat)
            })
        },
        clearAll(){
            this.polygonEditor.close()
            this.polygonEditor.setTarget()
            this.map.clearMap()
        },
        initPolyContextMenu(){
            //初始化多边形右键菜单
            this.polyContextMenu.addItem("编辑",(e)=>{
                this.polygonEditor.setTarget(this.selectedPolygon)
                this.polygonEditor.open()
            })
            this.polyContextMenu.addItem("编辑元数据",(e)=>{
                this.editorDialogVisible = true
            })
            this.polyContextMenu.addItem("新增图形",(e)=>{
                this.holeEdit = false;
                this.polygonEditor.setTarget()
                this.polygonEditor.open()
            })
            this.polyContextMenu.addItem("新增洞洞",(e)=>{
                this.polygonEditor.setTarget()
                this.polygonEditor.open()
                this.holeEdit = true;
            })
            this.polyContextMenu.addItem("删除",(e)=>{
                if(this.selectedPolygon.getExtData().text){
                    this.map.remove(this.selectedPolygon.getExtData().text)
                }
                this.map.remove(this.selectedPolygon)
                this.selectedPolygon = null
            })
        },
        savePolygonData(){
            this.form.polygon.setExtData({
                name: this.form.name,
                code: this.form.code,
                text: null
            })
            this.addText(this.form.polygon)   
            this.resetForm();
            this.editorDialogVisible = false;
        },
        resetForm(){
            this.form.name = "";
            this.form.code = "";
            this.form.polygon = null;
        },
        addText(polygon){
            if(polygon.getExtData().name == null) return;
            let center = polygon.getBounds().getCenter()
            if(polygon.getExtData().text != null) {
                polygon.getExtData().text.setText(polygon.getExtData().name)
                return polygon.getExtData().text
            }
            let mapText = new AMap.Text({
                                    text: polygon.getExtData().name,
                                    position: center,
                                    offset: 0,
                                    draggable : true,
                                    style: {
                                        fontSize: 14,
                                        fontWeight: 'bold',
                                        color: '#333',
                                        'background-color': 'transparent',
                                        border: 0
                                    }
                                })
            this.map.add(mapText)
            polygon.getExtData().text = mapText;
            return mapText;
        },
        createPolygon(){
            this.selectedPolygon=null;
            this.holeEdit = false;
            this.polygonEditor.close()
            this.polygonEditor.setTarget();
            this.polygonEditor.open();
        },
        startPolygonEdit(){
            this.polygonEditor.open();
        },
        stopPolygonEdit(){
            this.polygonEditor.close();
        },
        printPolygon(){ 
            this.activePolygons = new Map()
            this.regiondatas = []
            let overlays= this.map.getAllOverlays();
            let polygons = overlays.filter(overlay=>{
                return overlay.className == "Overlay.Polygon"&&overlay.getExtData().name!=null
            })
            polygons.forEach(polygon=>{
                if(this.activePolygons.has(polygon.getExtData().code)){
                    let values =  this.activePolygons.get(polygon.getExtData().code)
                    values.push(polygon)
                    this.activePolygons.set(polygon.getExtData().code,values)
                }else{
                    this.activePolygons.set(polygon.getExtData().code,[polygon])
                }
            })
            for (const [k, v] of this.activePolygons) {
                let centerPoints = []
                let shapes = []

                for (let i = 0; i < v.length; i++) {
                    let lnglat = v[i].getExtData().text.getPosition()
                    centerPoints.push(`Point(${lnglat.getLng()} ${lnglat.getLat()})` )
                }

                let regiondata = {
                    id: v[0].getExtData().id,
                    code: k,
                    name: v[0].getExtData().name,
                    centerPoint: centerPoints.join(","),
                    polygon: this.polygonToWKT(v),
                }
                this.regiondatas.push(regiondata)
            }
        },
        initMap(){
            AMapLoader.load({
            key:"90036e2b51384efe1cac1c1ba0608caf",             // 申请好的Web端开发者Key，首次调用 load 时必填
            version:"2.0",      // 指定要加载的 JSAPI 的版本，缺省时默认为 1.4.15
            plugins:[''],       // 需要使用的的插件列表，如比例尺'AMap.Scale'等
            }).then((AMap)=>{
                this.map = new AMap.Map("container",{  //设置地图容器id
                    viewMode:"2D",    //是否为3D地图模式
                    zoom:14,           //初始化地图级别
                });
                this.map.plugin(["AMap.PolygonEditor"],function(){ console.log("PolygonEditor多边形编辑器加载成功")})
                this.polygonEditor = new AMap.PolygonEditor(this.map);
                this.polyContextMenu = new AMap.ContextMenu()
                this.initPolyContextMenu();
                this.polygonEditor.on('add',(data)=>{
                    this.polygonEditor.addAdsorbPolygons(data.target); //吸附功能
                    let polygon = data.target;
                    this.addPolygonEvent(polygon)
                    if(this.selectedPolygon != null){
                        if(!this.holeEdit){
                            //合并多边形
                            // bug 合并成一个图形后样式需要统一，这里采用仍是多个多边形，在保存数据时，进行逻辑合并的方式
                            polygon.setExtData({
                                name: this.selectedPolygon.getExtData().name,
                                code: this.selectedPolygon.getExtData().code,
                                id: this.selectedPolygon.getExtData().id,
                            })
                            this.addText(polygon)
                        }else{
                            if(this.selectedPolygon.getExtData().hasHole){
                                let selectedPolygons =  this.selectedPolygon.getPath()
                                selectedPolygons.push(polygon.getPath())
                                this.selectedPolygon.setPath(selectedPolygons)
                            }else{
                                this.selectedPolygon.setPath([this.selectedPolygon.getPath(),polygon.getPath()])
                            }
                            this.selectedPolygon.getExtData().hasHole = true;
                            this.polygonEditor.close()
                        }
                    }
                    this.selectedPolygon = null
                })
            }).catch(e=>{
                console.log(e);
            })
        },
        initRootPplygon(){
            let polygon = new AMap.Polygon({
            path: suzhou,
            fillColor: '#ccebc5',
            strokeOpacity: 1,
            fillOpacity: 0.5,
            strokeColor: '#2b8cbe',
            strokeWeight: 1,
            strokeStyle: 'dashed',
            strokeDasharray: [5, 5],
            });
            polygon.on('mouseover', () => {
            polygon.setOptions({
                fillOpacity: 0.7,
                fillColor: '#7bccc4'
            })
            })
            polygon.on('mouseout', () => {
            polygon.setOptions({
                fillOpacity: 0.5,
                fillColor: '#ccebc5'

            })
            })
            this.map.add(polygon);
            this.map.setFitView([polygon])
        }
    },
    mounted(){
        this.initMap();
    }
}


export default mapdemo;
</script>

<style scoped src="@/assets/styles/map.css">

</style>